﻿using MCPlatform.MotionLib.Base;
using MCPlatform.MotionLib.Base.AssitantClass;
using MCPlatform.MotionLib.Base.Environment;
using MCPlatform.MotionLib.Base.Models;
using MCPlatform.MotionLib.Factory.Common;
using MCPlatform.MotionLib.Factory.LeadShine;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace MCPlatform.MotionLib.Factory
{
    public class LTFactory : IFactory
    {
        Dictionary<string, IImputation> ImputationList = new Dictionary<string, IImputation>();


        Dictionary<string, IMotion> MotionList = new Dictionary<string, IMotion>();

        Dictionary<string, IValve> ValveList = new Dictionary<string, IValve>();

        Dictionary<string, IIO> IOList = new Dictionary<string, IIO>();

        private event Action EstopEvent;
        public LTFactory()
        {
            ConstructValves();
            ConstructIOs();
            ConstructMotions();
            ConstructImptutations();
            EstopEvent += LTFactory_EstopEvent;

        }


        /// <summary>
        /// 每个轴都触发急停
        /// </summary>
        private void LTFactory_EstopEvent()
        {
            if (MotionList.Count != 0)
            {
                foreach (var motion in MotionList.Values)
                {
                    motion.Estop();
                }
            }
        }


        public Dictionary<string, IImputation> GetImputations(ushort count)
        {

            
            return ImputationList;

        }


        /// <summary>
        /// 获取轴
        /// </summary>
        /// <param name="count">轴数量</param>
        /// <returns></returns>
        public Dictionary<string, IMotion> GetMotions(ushort count)
        {

            //for (ushort i = 0; i < count; i++)
            //{
            //    MotionList.Add(new LTMotion() { MotionID = i, });
            //}

            return MotionList;

        }


        /// <summary>
        /// 获取阀，即气缸
        /// </summary>
        /// <param name="count">阀数量</param>
        /// <returns></returns>
        public Dictionary<string, IValve> GetValves(ushort count)
        {
            //if (ValveList.Count < count)
            //{
            //    return null;
            //  }

            return ValveList;
        }

        /// <summary>
        /// 获取IO模块
        /// </summary>
        /// <param name="count">模块数量</param>
        /// <returns></returns>
        public Dictionary<string, IIO> GetIOs(ushort count)
        {


            return IOList;
        }

        public void ConstructIOs()
        {
            var ioCofigs = GetIOParaModels();
            //Main Control
            IOList.Add("Start", new LTIO() 
            { 
                Address = 8, Type = "I", IOName = "启动按钮",
                IOConfig = ioCofigs?.FirstOrDefault(ioConfig => ioConfig.ControlName.Contains("启动按钮")) ?? new IOParaModel() 
            });

            IOList.Add("Stop", new LTIO()
            { 
                Address = 9, Type = "I", IOName = "停止按钮" ,
                IOConfig = ioCofigs?.FirstOrDefault(ioConfig => ioConfig.ControlName.Contains("停止按钮")) ?? new IOParaModel()
            });


            IOList.Add("Reset", new LTIO() 
            { 
                Address = 10, Type = "I", 
                IOName = "复位按钮",
                IOConfig = ioCofigs?.FirstOrDefault(ioConfig => ioConfig.ControlName.Contains("复位按钮")) ?? new IOParaModel()
            });

            IOList.Add("Manual", new LTIO()
            { 
                Address = 11, Type = "I",
                IOName = "手自动按钮",
                IOConfig = ioCofigs?.FirstOrDefault(ioConfig => ioConfig.ControlName.Contains("手自动按钮")) ?? new IOParaModel()
            });

            IOList.Add("E_stop", new LTIO() 
            {
                Address = 13, Type = "I", IOName = "急停按钮",
                IOConfig = ioCofigs?.FirstOrDefault(ioConfig => ioConfig.ControlName.Contains("急停按钮")) ?? new IOParaModel()
            });

            IOList.Add("Front Safety Grating", new LTIO() 
            { 
                Address = 19, Type = "I", IOName = "前安全光栅",
                IOConfig = ioCofigs?.FirstOrDefault(ioConfig => ioConfig.ControlName.Contains("前安全光栅")) ?? new IOParaModel()
            });

            IOList.Add("Rear Safety Grating", new LTIO() 
            { 
                Address = 20, Type = "I", IOName = "后安全光栅",
                IOConfig = ioCofigs?.FirstOrDefault(ioConfig => ioConfig.ControlName.Contains("后安全光栅")) ?? new IOParaModel()
            });


            IOList.Add("Start Led", new LTIO() 
            {
                Address =8, Type = "Q", IOName = "启动按钮灯",
                IOConfig = ioCofigs?.FirstOrDefault(ioConfig => ioConfig.ControlName.Contains("启动按钮灯")) ?? new IOParaModel()
            });

            IOList.Add("Stop Led", new LTIO() 
            { 
                Address = 9, Type = "Q", IOName = "停止按钮灯",
                IOConfig = ioCofigs?.FirstOrDefault(ioConfig => ioConfig.ControlName.Contains("停止按钮灯")) ?? new IOParaModel()
            });

            IOList.Add("Reset Led", new LTIO() 
            { 
                Address = 10, Type = "Q", 
                IOName = "复位按钮灯",
                IOConfig = ioCofigs?.FirstOrDefault(ioConfig => ioConfig.ControlName.Contains("复位按钮灯")) ?? new IOParaModel()
            });
            IOList.Add("E_stop Reset", new LTIO() 
            { 
                Address = 16, Type = "Q", IOName = "急停复位",
                IOConfig = ioCofigs?.FirstOrDefault(ioConfig => ioConfig.ControlName.Contains("急停复位")) ?? new IOParaModel()
            });


            IOList.Add("Red Led", new LTIO() 
            { 
                Address = 11, Type = "Q", IOName = "三色灯红灯",
                IOConfig = ioCofigs?.FirstOrDefault(ioConfig => ioConfig.ControlName.Contains("三色灯红灯")) ?? new IOParaModel()
            });

            IOList.Add("Green Led", new LTIO() 
            { 
                Address = 13, Type = "Q", IOName = "三色灯绿灯",
                IOConfig = ioCofigs?.FirstOrDefault(ioConfig => ioConfig.ControlName.Contains("三色灯绿灯")) ?? new IOParaModel()
            });
            IOList.Add("Yellow Led", new LTIO()
            { 
                Address = 12, Type = "Q", IOName = "三色灯黄灯",
                IOConfig = ioCofigs?.FirstOrDefault(ioConfig => ioConfig.ControlName.Contains("三色灯黄灯")) ?? new IOParaModel()
            });

            IOList.Add("Buzzer", new LTIO() 
            { 
                Address = 14, Type = "Q", IOName = "蜂鸣器",
                IOConfig = ioCofigs?.FirstOrDefault(ioConfig => ioConfig.ControlName.Contains("蜂鸣器")) ?? new IOParaModel()
            });

            IOList.Add("Light", new LTIO() 
            { 
                Address = 18, Type = "Q", IOName = "Led灯",
                IOConfig = ioCofigs?.FirstOrDefault(ioConfig => ioConfig.ControlName.Contains("Led灯")) ?? new IOParaModel()
            });
            //load

            IOList.Add("Leather Inplace Sensor", new LTIO() 
            { 
                Address = 51, Type = "I", IOName = "皮革到位传感器",
                IOConfig = ioCofigs?.FirstOrDefault(ioConfig => ioConfig.ControlName.Contains("皮革到位传感器")) ?? new IOParaModel()
            });

            //Cutting IO

            IOList.Add("Infrared Safety Sensor1", new LTIO() 
            { 
                Address = 40, Type = "I", IOName = "红外安全传感器1",
                IOConfig = ioCofigs?.FirstOrDefault(ioConfig => ioConfig.ControlName.Contains("红外安全传感器1")) ?? new IOParaModel()
            });
            IOList.Add("Infrared Safety Sensor2", new LTIO() 
            { 
                Address = 47, Type = "I", IOName = "红外安全传感器2",
                IOConfig = ioCofigs?.FirstOrDefault(ioConfig => ioConfig.ControlName.Contains("红外安全传感器2")) ?? new IOParaModel()
            });
            IOList.Add("Punching Motor", new LTIO() 
            { 
                Address = 20, Type = "Q", 
                IOName = "冲孔电机",
                IOConfig = ioCofigs?.FirstOrDefault(ioConfig => ioConfig.ControlName.Contains("冲孔电机")) ?? new IOParaModel()
            });
            IOList.Add("Cutting Motor", new LTIO()
            { 
                Address = 19, Type = "Q", IOName = "切割电机",
                IOConfig = ioCofigs?.FirstOrDefault(ioConfig => ioConfig.ControlName.Contains("切割电机")) ?? new IOParaModel()
            });
            IOList.Add("Cross Positioning Light", new LTIO() 
            { 
                Address = 17, Type = "Q", IOName = "红外十字定位灯",
                IOConfig = ioCofigs?.FirstOrDefault(ioConfig => ioConfig.ControlName.Contains("红外十字定位灯")) ?? new IOParaModel()
            });

            IOList.Add("Forward Motor", new LTIO() 
            { 
                Address = 38, Type = "Q", IOName = "调速电机正转",
                IOConfig = ioCofigs?.FirstOrDefault(ioConfig => ioConfig.ControlName.Contains("调速电机正转")) ?? new IOParaModel()
            });
            IOList.Add("Backward Motor", new LTIO()
            { 
                Address = 39, Type = "Q", IOName = "调速电机反转",
                IOConfig = ioCofigs?.FirstOrDefault(ioConfig => ioConfig.ControlName.Contains("调速电机反转")) ?? new IOParaModel()
            });
            IOList.Add("Safety Opto", new LTIO()
            { 
                Address = 32, Type = "I", IOName = "防撞光电",
                IOConfig = ioCofigs?.FirstOrDefault(ioConfig => ioConfig.ControlName.Contains("防撞光电")) ?? new IOParaModel()
            });
            //IOList.Add("Blower On", new LTIO() { Address = 37, Type = "Q", IOName = "鼓风机开启" });
            //  IOList.Add("Blower In", new LTIO() { Address = 16, Type = "I", IOName = "鼓风机反馈" });

            //Unload
            IOList.Add("Infrared Safety Sensor3", new LTIO() 
            { 
                Address = 59, Type = "I", IOName = "红外安全传感器3",
                IOConfig = ioCofigs?.FirstOrDefault(ioConfig => ioConfig.ControlName.Contains("红外安全传感器3")) ?? new IOParaModel()
            });
            IOList.Add("Infrared Safety Sensor4", new LTIO()
            { 
                Address = 60, Type = "I", IOName = "红外安全传感器4",
                IOConfig = ioCofigs?.FirstOrDefault(ioConfig => ioConfig.ControlName.Contains("红外安全传感器4")) ?? new IOParaModel()
            });
            IOList.Add("Infrared Safety Sensor5", new LTIO()
            { 
                Address = 67, Type = "I", IOName = "红外安全传感器5",
                IOConfig = ioCofigs?.FirstOrDefault(ioConfig => ioConfig.ControlName.Contains("红外安全传感器5")) ?? new IOParaModel()
            });
            IOList.Add("Infrared Safety Sensor6", new LTIO()
            { 
                Address = 68, Type = "I", IOName = "红外安全传感器6",
                IOConfig = ioCofigs?.FirstOrDefault(ioConfig => ioConfig.ControlName.Contains("红外安全传感器6")) ?? new IOParaModel()
            });

            IOList.Add("Infrared Safety Sensor7", new LTIO() 
            { 
                Address = 69, Type = "I", IOName = "红外安全传感器7",
                IOConfig = ioCofigs?.FirstOrDefault(ioConfig => ioConfig.ControlName.Contains("红外安全传感器7")) ?? new IOParaModel()
            });
            IOList.Add("Ionizer", new LTIO() 
            { 
                Address = 23, Type = "Q", IOName = "离子风机",
                IOConfig = ioCofigs?.FirstOrDefault(ioConfig => ioConfig.ControlName.Contains("离子风机")) ?? new IOParaModel()
            });


        }
        public void ConstructValves()
        {
           var valveConfigs =  GetCylinderParaModels();
            ValveList.Add("Load Jack Valve", new ValveBase()
            {
                ValveName = "上料料仓顶升气缸",
                WorkInAddress = 25,
                BaseInAddress = 24,
                WorkOutAddress = 21,
                BaseOutAddress = 0,
                IO = new LTIO() {},     
                ValveConfig = valveConfigs?.FirstOrDefault(valveConfig => valveConfig.ControlName.Contains("上料料仓顶升气缸")) ?? new ValveParaModel(),

            });

            ValveList.Add("Pull Drag Valve", new ValveBase()
            {
                ValveName = "上料牵引压接气缸",
                WorkInAddress = 27,
                BaseInAddress = 26,
                WorkOutAddress = 23,
                BaseOutAddress = 0,
                IO = new LTIO(),
                ValveConfig = valveConfigs?.FirstOrDefault(valveConfig => valveConfig.ControlName.Contains("上料牵引压接气缸")) ?? new ValveParaModel(),

            });


            ValveList.Add("Cutting Panel Vacuum", new ValveBase()
            {
                ValveName = "切割操作台吸盘",
                WorkInAddress = 16,
                BaseInAddress = 0,
                WorkOutAddress = 37,
                BaseOutAddress = 0,
                IO = new LTIO(),
                ValveConfig = valveConfigs?.FirstOrDefault(valveConfig => valveConfig.ControlName.Contains("切割操作台吸盘")) ?? new ValveParaModel(),

            });


            ValveList.Add("Cutting Panel Vacuum2", new ValveBase()
            {
                ValveName = "切割操作台吸盘2",
                WorkInAddress = 21,
                BaseInAddress = 0,
                WorkOutAddress = 21,
                BaseOutAddress = 0,
                IO = new LTIO(),
                ValveConfig = valveConfigs?.FirstOrDefault(valveConfig => valveConfig.ControlName.Contains("切割操作台吸盘2")) ?? new ValveParaModel(),

            });

            ValveList.Add("Cutting Press Vacuum", new ValveBase()
            {
                ValveName = "切割真空吸",
                // WorkInAddress = 31,
                // BaseInAddress = 32,
                WorkInAddress = 0,
                BaseInAddress = 0,
                WorkOutAddress = 30,
                BaseOutAddress = 0,
                IO = new LTIO(),
                ValveConfig = valveConfigs?.FirstOrDefault(valveConfig => valveConfig.ControlName.Contains("切割真空吸")) ?? new ValveParaModel(),

            });

            ValveList.Add("Cutting Punch Vacuum", new ValveBase()
            {
                ValveName = "打孔真空吸",
                // WorkInAddress = 31,
                // BaseInAddress = 32,
                WorkInAddress = 0,
                BaseInAddress = 0,
                WorkOutAddress = 22,
                BaseOutAddress = 0,
                IO = new LTIO(),
                ValveConfig = valveConfigs?.FirstOrDefault(valveConfig => valveConfig.ControlName.Contains("打孔真空吸")) ?? new ValveParaModel(),

            });


            ValveList.Add("Cutting Transport Valve", new ValveBase()
            {
                ValveName = "切割搬运气缸",
                WorkInAddress = 41,
                BaseInAddress = 42,
                WorkOutAddress = 25,
                BaseOutAddress = 24,
                IO = new LTIO(),
                ValveConfig = valveConfigs?.FirstOrDefault(valveConfig => valveConfig.ControlName.Contains("切割搬运气缸")) ?? new ValveParaModel(),

            });

            ValveList.Add("Cutting Finger Valve", new ValveBase()
            {
                ValveName = "切割手指气缸",
                WorkInAddress = 48,
                BaseInAddress =0,
                WorkOutAddress = 27,
                BaseOutAddress = 26,
                IO = new LTIO(),
                ValveConfig = valveConfigs?.FirstOrDefault(valveConfig => valveConfig.ControlName.Contains("切割手指气缸")) ?? new ValveParaModel(),

            });

            ValveList.Add("Cutting Press Valve", new ValveBase()
            {
                ValveName = "切割压紧气缸",
                WorkInAddress = 43,
                BaseInAddress = 44,
                WorkOutAddress = 28,
                BaseOutAddress = 29,
                IO = new LTIO(),
                ValveConfig = valveConfigs?.FirstOrDefault(valveConfig => valveConfig.ControlName.Contains("切割压紧气缸")) ?? new ValveParaModel(),

            });

            ValveList.Add("Cutting Punch Valve", new ValveBase()
            {
                ValveName = "打孔气缸",
                WorkInAddress = 0,
                BaseInAddress = 0,
                WorkOutAddress = 32,
                BaseOutAddress = 33,
                IO = new LTIO(),
                ValveConfig = valveConfigs?.FirstOrDefault(valveConfig => valveConfig.ControlName.Contains("打孔气缸")) ?? new ValveParaModel(),

            });

            ValveList.Add("Cutting Collect Valve", new ValveBase()
            {
                ValveName = "收废料气缸",
                WorkInAddress = 55,
                BaseInAddress = 54,
                WorkOutAddress = 35,
                BaseOutAddress = 34,
                IO = new LTIO(),
                ValveConfig = valveConfigs?.FirstOrDefault(valveConfig => valveConfig.ControlName.Contains("收废料气缸")) ?? new ValveParaModel(),

            });


            ValveList.Add("Unload Vacuum", new ValveBase()
            {
                ValveName = "码垛真空吸",
                //WorkInAddress = 65,
                //BaseInAddress = 66,
                WorkInAddress = 0,
                BaseInAddress = 0,
                WorkOutAddress = 36,
                BaseOutAddress = 0,
                IO = new LTIO(),
                ValveConfig = valveConfigs?.FirstOrDefault(valveConfig => valveConfig.ControlName.Contains("码垛真空吸")) ?? new ValveParaModel(),

            });




            

          
        }


        public void ConstructImptutations()
        {
            var CoordinateConfig = GetImputationParaModels();
            ImputationList.Add("Cutting Coordinate", new LTImputation()
            {
                ControlName = "切割坐标系",
                ImputationConfig = CoordinateConfig?.FirstOrDefault(coordinateConfig => coordinateConfig.ControlName.Contains("切割坐标系")) ?? new ImpMotionParaModel(),
                CrdNo = 0,
            });
        }

        public void ConstructMotions()
        {
            var AxisConfigs = GetMotionParaModels();

            MotionList.Add("Load Drag Axis", new LTMotion()
            {
                ControlName = "上料牵引轴",
                AxisConfig = AxisConfigs?.FirstOrDefault(axisConfig => axisConfig.ControlName.Contains("上料牵引轴")) ?? new MotionParaModel(),
                MotionID = 4,
            });
            MotionList.Add("Cutting X Axis", new LTMotion()
            {
                ControlName = "切割X轴",
                AxisConfig = AxisConfigs?.FirstOrDefault(axisConfig => axisConfig.ControlName.Contains("切割X轴")) ?? new MotionParaModel(),
                MotionID = 5,
            });

            MotionList.Add("Cutting Y Axis", new LTMotion()
            {
                ControlName = "切割Y轴",
                AxisConfig = AxisConfigs?.FirstOrDefault(axisConfig => axisConfig.ControlName.Contains("切割Y轴")) ?? new MotionParaModel(),
                MotionID =3,
            });

            MotionList.Add("Cutting Z Axis", new LTMotion()
            {
                ControlName = "切割Z轴",
                AxisConfig = AxisConfigs?.FirstOrDefault(axisConfig => axisConfig.ControlName.Contains("切割Z轴")) ?? new MotionParaModel(),
                MotionID = 1,
            });

            MotionList.Add("Cutting U Axis", new LTMotion()
            {
                ControlName = "切割U轴",
                AxisConfig = AxisConfigs?.FirstOrDefault(axisConfig => axisConfig.ControlName.Contains("切割U轴")) ?? new MotionParaModel(),
                MotionID = 0,
            });

            MotionList.Add("Unload X Axis", new LTMotion()
            {
                ControlName = "下料X轴",
                AxisConfig = AxisConfigs?.FirstOrDefault(axisConfig => axisConfig.ControlName.Contains("下料X轴")) ?? new MotionParaModel(),
                MotionID = 6,
            });

            MotionList.Add("Unload Y Axis", new LTMotion()
            {
                ControlName = "下料Y轴",
                AxisConfig = AxisConfigs?.FirstOrDefault(axisConfig => axisConfig.ControlName.Contains("下料Y轴")) ?? new MotionParaModel(),
                MotionID = 2,
            });

            MotionList.Add("Unload Z Axis", new LTMotion()
            {
                ControlName = "下料Z轴",
                AxisConfig = AxisConfigs?.FirstOrDefault(axisConfig => axisConfig.ControlName.Contains("下料Z轴")) ?? new MotionParaModel(),
                MotionID = 7,
            });
        }


        private List<ImpMotionParaModel>? GetImputationParaModels()
        {
            //读取轴配置信息上来
            // var motionConfigs = ReadConfigData.GetMotionParaConfigs();
            var ImpMotionConfigs = ReadConfigData.GetParaConfigs<ImpMotionParaModel>(Paths.ImpMotionConfigPaths);
            if (ImpMotionConfigs is null)
            {
                return null;
            }
            List<ImpMotionParaModel> ImpMotionParaModellist = new List<ImpMotionParaModel>();
            foreach (var config in ImpMotionConfigs)
            {
                ImpMotionParaModel impMotionParaModel = new ImpMotionParaModel();
                Base.AssitantClass.Common.AutoMapProperties(config, impMotionParaModel);
                ImpMotionParaModellist.Add(impMotionParaModel);
            }

            return ImpMotionParaModellist;
        }

        private List<MotionParaModel>? GetMotionParaModels()
        {
            //读取轴配置信息上来
            // var motionConfigs = ReadConfigData.GetMotionParaConfigs();
            var motionConfigs = ReadConfigData.GetParaConfigs<MotionParaModel>(Paths.MotionConfigPaths);
            if (motionConfigs is null)
            {
                return null;
            }
            List<MotionParaModel> MotionParaModellist = new List<MotionParaModel>();
            foreach (var config in motionConfigs)
            {
                MotionParaModel motionParaModel = new MotionParaModel();
                Base.AssitantClass.Common.AutoMapProperties(config, motionParaModel);
                MotionParaModellist.Add(motionParaModel);
            }

            return MotionParaModellist;
        }


        private List<ValveParaModel>? GetCylinderParaModels()
        {
            //读取配置信息上来

            var valveConfigs = ReadConfigData.GetParaConfigs<ValveParaModel>(Paths.ValveConfigPaths);
            if (valveConfigs is null)
            {
                return null;
            }
            return valveConfigs;
           
        }

        private List<IOParaModel>? GetIOParaModels()
        {
            //读取配置信息上来

            var ioConfigs = ReadConfigData.GetParaConfigs<IOParaModel>(Paths.IOConfigPaths);
            if (ioConfigs is null)
            {
                return null;
            }
            return ioConfigs;
           
        }


    }
}
